如果在使用aws lambda中,你的lambda函数需要访问aws的其他服务,例如EFS、RDS,那么大概率需要将你的lambda和efs放置在同一vpc中(不在同一vpc的情况下你可以使用endpoint),这个时候即使你的lambda是在公开子网(public subnet)中也是是没有访问互联网的能力的,这是因为你的lambda只有子网的ip10.0.0.0,流量路由到互联网网关的时候会被网关丢弃,因为你没有配置公网ip。本文会给出几个解决方案,并分析优缺点。
因为aws的文档大部分是英文,中文文档都是机翻,所以有些专有名词的翻译就很别扭,所以干脆直接用英文。
前言
正如前面所说,你的lambda函数
所在的vpc
需要配置公网ip
才能拥有访问互联网的能力。你可能会说,为什么我平时用的lambda不需要加入vpc呢?
这是因为:
- 你的lambda没有手动配置vpc。如果你的lambda没有手动配置vpc,那么aws会把你的lambda放进aws自己管理的vpc中,在该vpc中拥有公网ip,你的lambda可以访问互联网,但是你的lambda函数并不能访问该vpc下的其他aws服务(当然不能,难道你还能访问aws他自己的私有服务吗)
- 你的lambda并没有使用到其他aws服务。要使用其他aws服务,则该服务一定是要加入到你自己的vpc中的,例如你要把信息写进
json
文件并持久化,你需要s3或者EFS;例如你要访问ec2实例或RDS数据库。如果只是临时写入文件则可以在/tmp
目录下写入,lambda运行结束则会被清空,不能持久化。
要让lambda拥有同时访问互联网和vpc下的服务的能力,首先你要有公网ip,另外你的lambda能访问vpc下的服务。
我查阅了网上提到的几种方法,并总结下来
存在的解决方案有:
- 配置
nat网关
。 - 配置
endpoint
。将你的程序解耦,分为两个lambda函数,一个用于访问互联网,另一个访问aws服务,二者通过endpoint进行通讯。 - 通过
API gateway
。同样地,你的程序需要解耦,其中用于访问aws服务的lambda被主lambda函数通过API调用。 - 通过aws lambda
api
。使用aws sdk(python使用boto3
),通过invoke方法同步或异步调用另一个lambda。
解决方案
配置nat网关
这是官方推荐的方法。
如何配置
新建一个vpc,选择带有公网子网和私有子网的模板,然后勾选nat网关就可以。在可视化界面中你可以看到私有子网通过路由表(route table)将流量路由到nat网关。你把你的lambda和aws服务放进私有子网内,你的lambda就拥有了同时访问互联网和vpc下的aws服务的能力。路由表会根据destination
帮你处理好一切。
优缺点
最简单也最贵。单单是一个nat网关开着它就要30美元一个月,转发的流量还需要另外收费。不清楚公网ip是否另外收费
配置endpoint
aws设置endpoint的目的是为了让处于不同的vpc下的服务不通过互联网而通过aws的内部网络相互通讯,从而减少安全风险。
如何配置
利用这个特性,你可以在将需要访问互联网的lambda放在aws他自己管理的vpc中(在创建lambda的时候默认会放进该vpc),将另一个lambda放到你的vpc中,该lambda函数用于访问同vpc下的aws服务,例如RDS。前者lambda通过endpoint访问后者。
值得注意的是,endpoint
是安装在服务消费者(service consumers
)上的,在上面的例子中,假设我是希望能访问互联网的lambda访问处于自定义vpc中的lambda,读取RDS数据并发送邮件。在这里,服务消费者是访问互联网的lambda,服务提供者(service providers
)是处于自定义vpc中的lambda,前面提到,endpoint
应该被安装在服务消费者——也就是访问互联网的lambda中,但是,该lambda是放在aws自己管理的vpc中的,我们没有权限去创建一个endpoint
,只能改变思路,就像下面的图所示,把处于自定义vpc中的lambda作为服务消费者,读取数据库,之后通过endpoint
调用vpc外面的lambda。
NOTE
在你的lambda中,可以通过编程的方式使用aws sdk(python是boto3
)链接endpoint。sdk通常是发送一个http请求
来调用endpoint
。
优缺点
优点
- 费用比nat低
- 由于解耦,程序逻辑更加清晰,并且能提高复用率。如果你使用RDS,需要使用
RDS proxy
来复用同一个数据库连接。
缺点
- 高延迟+双重冷(热)启动
- 受到lambda的并发限制。免费账号只有10个并发,如果你要多次读写数据库则速度会很慢
通过API gateway
API gateway
的最佳用途应该是用来写REST api
,你可以通过API gateway
调用lambda函数
如何配置
编写两个lambda,其中用于访问aws服务的lambda设置API gateway
触发器(trigger
),因而用于访问互联网的lambda可以通过发送http请求
到该url而调用另一个lambda,进而访问aws服务。
优缺点
优点
- 有免费额度
- 不用设置endpoint
- 可以使用
http
来调用,调用起来更加方便 - 由于解耦,程序逻辑更加清晰,并且能提高复用率。如果你使用RDS,需要使用RDS proxy来复用同一个数据库连接。
缺点
- 高延迟+双重冷(热)启动
- 受到lambda的并发限制。免费账号只有10个并发,如果你要多次读写数据库则速度会很慢
通过aws lambda api
和其他aws服务一样,lambda也有自己的api。其中就包括调用lambda函数的invoke
方法。
如何配置
如果你使用python
,详见invoke
优缺点
优点
- api本身免费,运行的lambda有免费额度
- 由于解耦,程序逻辑更加清晰,并且能提高复用率。如果你使用RDS,需要使用RDS proxy来复用同一个数据库连接。
缺点
- 只能通过aws sdk使用,否则你要自行编写认证程序
- 高延迟+双重冷(热)启动
- 受到lambda的并发限制。免费账号只有10个并发,如果你要多次读写数据库则速度会很慢